﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Web.Security;
using System.Text.RegularExpressions;
using System.Reflection;
namespace Common
{
    /// <summary>
    /// 安全相关常用
    /// </summary>
    public partial class SecurityHelper
    {
        public sealed class Safe
        {
            #region 加密解密
            //MD5加密
            /// <summary>
            /// MD5加密
            /// </summary>
            /// <param name="str">要加密的字符串</param>
            /// <param name="code">16或者32</param>
            /// <returns>MD5字符串</returns>
            public static string MD5(string str, int code)
            {
                StringBuilder pwd = new StringBuilder(code);
                MD5 md5 = System.Security.Cryptography.MD5.Create();//实例化一个md5对像
                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
                byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
                for (int i = (s.Length - code / 2) / 2; i < (s.Length + code / 2) / 2; i++)
                {
                    // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
                    pwd.Append(s[i].ToString("x2"));
                }
                return pwd.ToString();
            }

            //MD5加密(32)
            /// <summary>
            /// MD5加密(32)
            /// </summary>
            /// <param name="str">要加密的字符串</param>
            /// <returns>32位MD5字符串</returns>
            public static string MD5(string str)
            {
                return MD5(str, 32);
            }

            //MD5加密前几位
            /// <summary>
            /// MD5加密前几位
            /// </summary>
            /// <param name="str">要加密的字符串</param>
            /// <param name="code">16或者32</param>
            /// /// <param name="len">长度</param>
            /// <returns>MD5字符串</returns>
            public static string MD5(string str, int code, int len)
            {
                StringBuilder pwd = new StringBuilder(code);
                MD5 md5 = System.Security.Cryptography.MD5.Create();//实例化一个md5对像
                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
                byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
                int l = 0;
                for (int i = (s.Length - code / 2) / 2; i < (s.Length + code / 2) / 2; i++)
                {
                    // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
                    pwd.Append(s[i].ToString("x2"));
                    l += 2;
                    if (l == len)
                    {
                        break;
                    }
                    else if (l > len)
                    {
                        pwd.Remove(pwd.Length - 1, 1);
                        break;
                    }
                }
                return pwd.ToString();
            }
            /// <summary>
            /// 获取加密后的密码
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            public static string PasswordMD5(string str)
            {
                string MD5Str = MD5(str);
                return MD5Str.Substring(8,8).ToLower();
            }
            //SHA1加密
            /// <summary>
            /// SHA1加密
            /// </summary>
            /// <param name="str">要加密的字符串</param>
            /// <returns>SHA1加密后字符串</returns>
            public static string SHA1(string str)
            {
                if (str == null) str = "";
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "SHA1").ToLower();
            }

            //随机Base64字符串
            /// <summary>
            /// 随机Base64字符串
            /// </summary>
            /// <param name="len">字符串长度(4的倍数)</param>
            /// <returns>随机Base64字符串</returns>
            public static string NewRNGBase64Str(int len)
            {
                len = len / 4 * 3 - 2;
                byte[] bytSalt = new byte[len];
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                rng.GetBytes(bytSalt);
                return Convert.ToBase64String(bytSalt);
            }

            //Forms加密
            /// <summary>
            /// Forms加密
            /// </summary>
            /// <param name="s">要加密的字符串</param>
            /// <returns>加密结果</returns>
            public static string FormsEncrypt(string s)
            {
                if (s == null)
                    s = "";
              FormsAuthenticationTicket aft = new FormsAuthenticationTicket(1, s, DateTime.Now, DateTime.Now, false, "");
                return FormsAuthentication.Encrypt(aft);
            }

            //Forms解密
            /// <summary>
            /// Forms解密
            /// </summary>
            /// <param name="s">要解密的字符串</param>
            /// <returns>解密结果</returns>
            public static string FormsDecrypt(string s)
            {
                if (s == null)
                    return "";
                FormsAuthenticationTicket tkt = FormsAuthentication.Decrypt(s);
                if (tkt == null)
                    return "";
                return tkt.Name;
            }

            //Base16加密
            /// <summary>
            /// Base16加密
            /// </summary>
            /// <param name="s">要加密的字符串</param>
            /// <returns>加密结果</returns>
            public static string Base16Encrypt(string s)
            {
                if (string.IsNullOrEmpty(s))
                {
                    return "";
                }
                byte[] bytes = Encoding.UTF8.GetBytes(s);
                StringBuilder sb = new StringBuilder();
                foreach (byte b in bytes)
                {
                    sb.Append(b.ToString("x2"));
                }
                return sb.ToString();
            }

            //Base16解密
            /// <summary>
            /// Base16解密
            /// </summary>
            /// <param name="s">要解密的字符串</param>
            /// <returns>解密结果</returns>
            public static string Base16Decrypt(string s)
            {
                if (string.IsNullOrEmpty(s) || s.Length % 2 > 0)
                {
                    return "";
                }
                byte[] bytes = new byte[s.Length / 2];
                try
                {
                    for (int i = 0; i < s.Length; i += 2)
                    {
                        bytes[i / 2] = Convert.ToByte(s.Substring(i, 2), 16);
                    }
                }
                catch
                {
                    return "";
                }
                return Encoding.UTF8.GetString(bytes);
            }

            public static string strConfigAECKey = "vMzWYIdy0PqbaDDpygLHwevXW9dG5W";
            public static string strVersionAECKey = "Yks3GoRlEceJsR4Xfdr84qWRrKFxJn";
            /// <summary>
            /// AES加密算法
            /// </summary>
            /// <param name="plainText">明文字符串</param>
            /// <param name="strKey">密钥</param>
            /// <returns>返回加密后的密文字节数组</returns>
            public static string AESEncrypt(string plainText, string strAECKey)
            {
                try
                {
                    //分组加密算法
                    RijndaelManaged aes = new RijndaelManaged();
                    byte[] inputByteArray = Encoding.UTF8.GetBytes(plainText);//得到需要加密的字节数组

                    //设置密钥及密钥向量
                    aes.Key = Encoding.UTF8.GetBytes(GetMD5(strAECKey));
                    aes.IV = Encoding.UTF8.GetBytes(GetMD5(strAECKey).Substring(8, 16));
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    ICryptoTransform transform = aes.CreateEncryptor();
                    byte[] buffer = transform.TransformFinalBlock(inputByteArray, 0, inputByteArray.Length);

                    //System.IO.MemoryStream ms = new System.IO.MemoryStream();

                    //CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);

                    //cs.Write(inputByteArray, 0, inputByteArray.Length);
                    //cs.FlushFinalBlock();

                    StringBuilder ret = new StringBuilder();
                    foreach (byte b in buffer)
                    {
                        ret.AppendFormat("{0:x2}", b);
                    }
                    return ret.ToString();
                }
                catch
                {
                    return plainText;
                }
            }

            /// <summary>
            /// AES解密
            /// </summary>
            /// <param name="cipherText">密文字节数组</param>
            /// <param name="strKey">密钥</param>
            /// <returns>返回解密后的字符串</returns>
            public static string AESDecrypt(string cipherText, string strAECKey)
            {
                try
                {
                    RijndaelManaged aes = new RijndaelManaged();

                    int len;
                    len = cipherText.Length / 2;
                    byte[] inputByteArray = new byte[len];
                    int x, i;
                    for (x = 0; x < len; x++)
                    {
                        i = Convert.ToInt32(cipherText.Substring(x * 2, 2), 16);
                        inputByteArray[x] = (byte)i;
                    }

                    //byte[] inputByteArray = Encoding.UTF8.GetBytes(cipherText);
                    //设置密钥及密钥向量
                    aes.Key = Encoding.UTF8.GetBytes(GetMD5(strAECKey));
                    aes.IV = Encoding.UTF8.GetBytes(GetMD5(strAECKey).Substring(8, 16));
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    ICryptoTransform transform = aes.CreateDecryptor();
                    byte[] buffer = transform.TransformFinalBlock(inputByteArray, 0, inputByteArray.Length);

                    //System.IO.MemoryStream ms = new System.IO.MemoryStream();
                    //CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);
                    //cs.Write(inputByteArray, 0, inputByteArray.Length);
                    //cs.FlushFinalBlock();
                    string strDecrypt = Encoding.UTF8.GetString(buffer);
                    return strDecrypt;

                }
                catch
                {
                    return cipherText;
                }
            }
            public static string GetMD5(string str)
            {
                StringBuilder sb = new StringBuilder();
                foreach (byte b in System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(str)))
                {
                    sb.Append(b.ToString("X2"));
                }
                return sb.ToString();
            }

            #endregion

            
            public static string PadintLeftZero(int i, int Lenth)
            {
                string str = i.ToString().PadLeft(Lenth, '0');
                return str;
            }

            public static string AuditTyleName(string auditTyleID)
            {
                string result = "未知";
                switch (auditTyleID)
                {
                    case "001":
                        result = "收货审核";
                        break;
                    case "002":
                        result = "运单审核";
                        break;
                    case "003":
                        result = "废单审核";
                        break;
                    case "004":
                        result = "商品审核";
                        break;
                    default:
                        result = "未知";
                        break;
                }
                return result;
            }
            public static string AuditTyleID(string auditTyleID)
            {
                string result = "000";
                switch (auditTyleID)
                {
                    case "收货审核":
                        result = "001";
                        break;
                    case "运单审核":
                        result = "002";
                        break;
                    case "废单审核":
                        result = "003";
                        break;
                    case "商品审核":
                        result = "004";
                        break;
                    default:
                        result = "000";
                        break;
                }
                return result;
            }


            /// <summary>
            /// keyvalue Get Value   12~店长   获取 店长
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetValue(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split('~');

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[1];
                }

                return result;
            }

            /// <summary>
            /// keyvalue Get Key  12~店长   获取 12
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetKey(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split('~');

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[0];
                }

                return result;
            }



            /// <summary>
            /// keyvalue Get Value   12:店长   获取 店长
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetValue2(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split(':');

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[1];
                }

                return result;
            }

            /// <summary>
            /// keyvalue Get Key  12:店长   获取 12
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetKey2(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split(':');

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[0];
                }

                return result;
            }



            /// <summary>
            /// keyvalue Get Value   12:店长   获取 店长
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetValue3(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split(new string[] { "{[11#]}" }, StringSplitOptions.None);

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[1];
                }

                return result;
            }

            /// <summary>
            /// keyvalue Get Key  12:店长   获取 12
            /// </summary>
            /// <param name="positionKeyValue"></param>
            /// <returns></returns>
            public static string keyvalueGetKey3(string keyValue)
            {
                string result = "";

                string[] pKV = keyValue.Split(new string[] { "{[11#]}" }, StringSplitOptions.None);

                if (pKV != null && pKV.Length > 1)
                {
                    result = pKV[0];
                }

                return result;
            }


            #region 判断是否为数字
            /// <summary>
            /// 判断是否为数字
            /// </summary>
            /// <param name="str">要判断的字符串</param>
            /// <returns>是数字为true 非数字 false</returns>
            public static bool Is_Number(string str)
            {
                bool bRet = true;

                if (str.Trim() == "")
                {
                    bRet = false;
                }
                else
                {
                    ASCIIEncoding AE = new ASCIIEncoding();
                    byte[] bArray = AE.GetBytes(str);

                    for (int i = 0; i < bArray.Length; i++)
                    {
                        if (bArray[i] < 47 || bArray[i] > 57)
                        {
                            bRet = false;
                            break;
                        }
                    }
                }
                return bRet;
            }
            #endregion


            #region arscii码取字符串长度
            /// <summary>
            /// arscii码取字符串长度
            /// </summary>
            /// <param name="from_str"></param>
            /// <returns></returns>
            public static int get_StrLength(string _SourceStr)
            {
                int len = 0;
                for (int i = 0; i < _SourceStr.Length; i++)
                {
                    if (Is_Haizi(_SourceStr.Substring(i, 1)))
                    {
                        len += 2;
                    }
                    else
                    {
                        len += 1;
                    }
                }

                return len;
            }
            #endregion


            #region 判断是否为汉字
            /// <summary>
            /// 判断是否为汉字
            /// </summary>
            /// <param name="_SourceStr"></param>
            /// <returns></returns>
            public static bool Is_Haizi(string _SourceStr)
            {
                Regex reg = new Regex("[^x00-xff]");
                bool isMatched = reg.IsMatch(_SourceStr);

                return isMatched;
            }
            #endregion

            /// <summary>
            /// 去掉单号返回整形的单号 例如： 0010000124  返回  124
            /// </summary>
            /// <param name="orderStr"></param>
            /// <returns></returns>
            public static int GetOrderCode(string orderStr)
            {
                int result = 0;
                if (Is_Number(orderStr.Trim()) == true)
                {
                    if (orderStr.Trim().Length > 3)
                    {
                        result = int.Parse(orderStr.Trim().Substring(3));
                    }
                }
                return result;
            }

            /// <summary>
            /// 得到当前时间   用于消息提醒结束时间判断
            /// </summary>
            /// <returns></returns>
            public static string GetCheckTime_ServerDateTime()
            {
                return DateTime.Now.ToString("yyyy-MM-dd");
            }

            /// <summary>
            /// 文件加密
            /// </summary>
            /// <param name="strFileFullPath"></param>
            /// <returns></returns>
            public static string GetFileMd5Hash(string strFileFullPath)
            {
                // Create a new instance of the MD5CryptoServiceProvider object.
                

               System.IO.FileStream fst = null;
                try
                {
                   
                    fst = new System.IO.FileStream(strFileFullPath, System.IO.FileMode.Open);
                    System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                    // Convert the input string to a byte array and compute the hash.
                    byte[] data =md5 .ComputeHash(fst);

                    // Create a new Stringbuilder to collect the bytes
                    // and create a string.
                    StringBuilder sBuilder = new StringBuilder();

                    // Loop through each byte of the hashed data 
                    // and format each one as a hexadecimal string.
                    for (int i = 0; i < data.Length; i++)
                    {
                        sBuilder.Append(data[i].ToString("x2"));
                    }

                    fst.Close();
                    // Return the hexadecimal string.
                    return sBuilder.ToString().ToLower();
                }
                catch (System.Exception ex)
                {
                    if (fst != null)
                        fst.Close();
                    return "";
                }
                finally
                {
                }
            }

            /// <summary>
            /// SQL防注入
            /// </summary>
            /// <param name="Para"></param>
            /// <returns></returns>
            public static bool CheckSqlKeyword(string Para)
            {
                //SQL防注入
                string Sql_1 = System.Configuration.ConfigurationManager.AppSettings["SqlKeyWord"];
                if (!string.IsNullOrWhiteSpace(Sql_1))
                {
                    string[] sql_c = Sql_1.Split('|');


                    if (Para.Trim().Length > 0)
                    {
                        foreach (string sl in sql_c)
                        {
                            if (Para.ToString().ToLower().IndexOf(sl.Trim()) >= 0)
                            {
                                return false;
                            }
                        }
                    }
                }
                return true;
            }


            /// <summary>
            /// 转义实体中为字符串类型字段的值
            /// </summary>
            /// <typeparam name="T">实体类</typeparam>
            /// <param name="model">需要转义的实体</param>
            /// <returns>转义后的实体</returns>
            public static T GetEncodeModel<T>(T model)
            {
                Type type = model.GetType();

                foreach (PropertyInfo p in type.GetProperties())
                {
                    object valueObj = p.GetValue(model, null);
                    if (valueObj != null && valueObj.GetType() == typeof(string))
                    {
                        string value = StringHelper.UrlEncode(valueObj.ToString());

                        p.SetValue(model, value, null);
                    }
                }

                return model;
            }
            /// <summary>
            /// 解码实体中转义过的为字符串类型字段的值
            /// </summary>
            /// <typeparam name="T">实体类</typeparam>
            /// <param name="model">需要转义的实体</param>
            /// <returns>转义后的实体</returns>
            public static T GetDecodeModel<T>(T model)
            {
                Type type = model.GetType();

                foreach (PropertyInfo p in type.GetProperties())
                {
                    object valueObj = p.GetValue(model, null);
                    if (valueObj != null && valueObj.GetType() == typeof(string))
                    {
                        string value = StringHelper.SpecialChar(StringHelper.UrlDecode(valueObj.ToString()));

                        p.SetValue(model, value, null);
                    }
                }

                return model;
            }
        }
    }
}
